#include <kernel/sign_kernel.h>
#include <save/SaveInfo.h>
#include <log/log_err.h>
#include "Template.hpp"
#include <iostream>
#include <mutex>
#include <cstdlib>
#include <thread>
#include <algorithm>
#include <value/colors/ResColor.h>
#include <value/strings/ResString.h>
#include <value/layout/Layout.h>
#include "NotifyQueue.h"
#include "DataTime.h"
#include "WifiUpgrade.h"
#include <test/fanttai/WifiText.h>

using namespace std;
class testDemo
{
public: 
    testDemo(int num) :num(num){
        buffer = new char[ 128 ];
        snprintf(buffer, sizeof(buffer), "buffer %d", num);
        std::cout << "调用构造函数" << endl;
    }
    testDemo(const testDemo& other) :num(other.num) {
        buffer = new char[ 128 ];
        memcpy(buffer, other.buffer, sizeof(buffer));
        std::cout << "调用拷贝构造函数" << endl;
    }
    testDemo(testDemo&& other) :num(other.num), buffer(other.buffer) {
        other.buffer = nullptr;
        std::cout << "调用移动构造函数" << endl;
    }
    ~testDemo() {
        if (buffer != nullptr) {
            delete [] buffer;
        }
    }
    std::string toString() const {
        if (buffer == nullptr) {
            return std::string();
        }
        return std::string(buffer);
    }
private:
    int num;
    char* buffer;
};

void for_text() /* for循环分析 */
{
    std::vector<testDemo> testDemoList = { 1, 2, 3, 4, 5, 6, 7, 8 };
    SIGNWAY_LOGI(">>>>>>>>>>>>>>>>>>");
    for (auto const& value : testDemoList) {

    }
}

void emplace_back()
{
    cout << "emplace_back:" << endl;
    std::vector<testDemo> demo1;
    demo1.emplace_back(2);
    cout << "push_back:" << endl;
    std::vector<testDemo> demo2;
    demo2.push_back(2);
    SIGNWAY_LOGI(">>>>>>>>>>>>>>>>>>>");
    testDemo t1(1);
    cout << t1.toString() << endl;
    SIGNWAY_LOGI(">>>>>>>>>>>>>>>>>>>");
    testDemo t2 = t1;
    cout << t1.toString() << endl;
    cout << t2.toString() << endl;
    SIGNWAY_LOGI(">>>>>>>>>>>>>>>>>>>");
    testDemo t3(std::move(t1));
    cout << t1.toString() << endl;
    cout << t3.toString() << endl;
}

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
bool cmp(int a, int b) {
    return a < b;
}

void lambda_fun()
{
    std::vector<int> myvec{ 3, 2, 5, 7, 3, 2 };
    std::vector<int> lbvec(myvec);

    std::sort(myvec.begin(), myvec.end(), cmp); // 旧式做法
    std::cout << "predicate function:" << std::endl;
    for (int it : myvec)
        std::cout << it << ' ';
    std::cout << std::endl;

    std::sort(lbvec.begin(), lbvec.end(), [] (int a, int b) -> bool {return a < b;});   // Lambda表达式
    std::cout << "lambda expression:" << std::endl;
    for (int it : lbvec)
        std::cout << it << ' ';

    std::thread t([] (const char* name) -> void {
        SIGNWAY_LOGI("%s", name); 
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }, "hello world");
    t.join();
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/

void thread_task(int n) {
    std::this_thread::sleep_for(std::chrono::seconds(n));
    std::cout << "hello thread "
        << std::this_thread::get_id()
        << " paused " << n << " seconds" << std::endl;
}

int thread_text()
{
    std::queue<std::thread> threads;
    std::cout << "Spawning 5 threads...\n";
    for (int i = 0; i < 5; i++) {
        threads.push(std::thread(thread_task, i + 1));
    }
    std::cout << "Done spawning threads! Now wait for them to join\n";
    while (!threads.empty()) {
        threads.front().join();
        threads.pop();
    }
    std::cout << "All threads joined.\n";

    return EXIT_SUCCESS;
}

class A {
public:
    A(){}
    virtual ~A(){}
    int a;
};

class B : virtual public A {
public:
    // int b;
};

class C : virtual public A , public B {
public:
    int c;
};

int& fun(int &n)
{
    int b = n;
    b++;
    return b;
}

void succeed_test()
{
    const int count = 100;
    srand(time(NULL));

#if 0
    for (size_t i = 0; i < count; i++)
    {
        int a = rand() % 1000;
        // SIGNWAY_LOGI("a = %d", a);
        // SIGNWAY_LOGI("a/5 = %.2f", (double)a/5);
        // SIGNWAY_LOGI("a/5 = %d", DIV_ROUND_CLOSEST(a, 5));
        if ((int)((double)a/5 + 0.5) == DIV_ROUND_CLOSEST(a, 5)) {
            SIGNWAY_LOGI("ok");
        } else {
            SIGNWAY_LOGE("err");
        }
    }
#endif 

#if 0
    int err = 0;
    for (size_t i = 0; i < count * 1000; i++)
    {
        int a = rand() % 1000;
        // SIGNWAY_LOGI("%.2f分", (double)a/60);
        // SIGNWAY_LOGI("%d分", roundup(a, 60)/60);
        double ret = roundup(a, 60)/60 - (double)a/60;
        if (ret < 1 && ret >= 0) {
            SIGNWAY_LOGI("ok");
        } else {
            err++;
            SIGNWAY_LOGE("err");
        }
    }
    SIGNWAY_LOGI("%d", err);
    SIGNWAY_LOGI(">>>>>>>>>>>>>>>>>>>>>>>>>>");
    // for (size_t i = 0; i < count; i++)
    // {
    //     int a = rand() % 1000;
    //     SIGNWAY_LOGI("%.2f分", (double)a/60);
    //     SIGNWAY_LOGI("%d分", rounddown(a, 60)/60);
    // }
#endif

}

int main(int argc, char const *argv[])
{
#if 0
    SIGNWAY_LOGI("%s", argv[0]);

    SaveInfo* info = SaveInfo::getInstance();
    clock_t start = clock();
    info->saveValue();
    info->loadValue();
    clock_t end = clock();

    SIGNWAY_LOGI("run time = %d", end - start);
#endif

#if 0
    clock_t start = clock();
    SIGNWAY_LOGI("%06X", ResColor::getColor("colorPrimary1"));
    clock_t end = clock();

    SIGNWAY_LOGI("run time = %d", end - start);
#endif

#if 0
    clock_t start = clock();
    SIGNWAY_LOGI("app_main = %s", ResString::getString("app_name"));
    clock_t end = clock();

    SIGNWAY_LOGI("run time = %d", end - start);
#endif

#if 0
    clock_t start = clock();
    Layout layout;
    layout.LoadFile("res/layout/activity_main.xml");
    clock_t end = clock();

    SIGNWAY_LOGI("run time = %d", end - start);
#endif

#if 0
    if (argc < 3) {
        SIGNWAY_LOGE("Usage rename point_ 1");
        SIGNWAY_LOGE("Usage rename point_ pointer 1");
        return -1;
    }
    if (argc == 3) {
        automaticRenamingWidget(argv[1], argv[1], atoi(argv[2]));
    } else if (argc == 4) {
        automaticRenamingWidget(argv[1], argv[2], atoi(argv[3]));
    }
#endif

#if 0
    auto data = DataTime::getInstance();
    while (true) {
        data->timerTrigger(nullptr);
        usleep(10);
    }

#endif

#if 0
    // NotifyQueue::getInstance()->start();
    SIGNWAY_LOGI("主线程开始。。。");
    sleep(1);
    DataTime::getInstance()->syncTime();
    sleep(200);
    SIGNWAY_LOGW("主线程退出。。。");
#endif

#if 0
    thread_text();
#endif


#if 0
    emplace_back();
#endif

#if 0
    lambda_fun();
#endif

#if 0
    succeed_test();/* 继承测试 */
#endif

#if 0
    for_text();/* for循环分析 */
#endif

#if 0
    uniontext();
#endif

#if 0
    WIFI_ZKW_STATUS wifiZkwStatusA;
    WIFI_ZKW_STATUS wifiZkwStatusB;
    bzero(&wifiZkwStatusA, sizeof(wifiZkwStatusA));
    bzero(&wifiZkwStatusB, sizeof(wifiZkwStatusB));
    wifiZkwStatusA.errorCode = 1;
    wifiZkwStatusB.errorCode = 1;
    cout << IsTheSame(&wifiZkwStatusA, &wifiZkwStatusB) << endl;
#endif

#if 1
    WifiUpgrade::test();
#endif

#if 1
    std::cout << "11 6 的最大公约数为" << gcd(11, 6) << std::endl;
#endif 

    return 0;
}

